package org.ricks.actor;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author chenwei
 * @Description:actor概念
 * counter 处理方式，如果机器人不睡眠循环发送消息，这时候就会出现消息堆积，而消息任务会递归一直到队列消息消费殆尽
 * 如果队列消息堆积到一定程度，递归循环达到栈内存上限 就会栈内存溢出
 * @date 2022/9/1913:52
 */
public class Actor implements IActor{

    private ExecutorService execute;
    private LinkedTransferQueue<ActorRunnable> queues = new LinkedTransferQueue();
    private AtomicInteger counter = new AtomicInteger();
    private final Worker worker;

    public Actor(ExecutorService execute) {
        this.worker = new Worker();
        this.execute = execute;
    }

    @Override
    public void execute(String key, Runnable task) {
        execute(new ActorRunnable(key,task));
    }

    @Override
    public void execute(ActorRunnable task) {
        queues.offer(task);
//        if(waitSize() > 500) Logger.info("offer 超出队列 size:" + waitSize()  + " counter num: " + counter.getAndIncrement());
//        if (counter.getAndIncrement() == 0) {
            execute.execute(worker);
//        }
    }

    @Override
    public int waitSize() {
        return queues.size();
    }

    @Override
    public void shutdown() {
        execute.shutdown();
        while (!execute.isTerminated()) sleep(100);
    }

    private void sleep(int num) {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    class Worker implements Runnable {

        @Override
        public void run() {
//            while (counter.decrementAndGet() >= 0) {
                try {
                    ActorRunnable worker = queues.poll();
                    worker.run();
                } catch (Exception e) {
                    e.printStackTrace();
                }
//            }
//            if(counter.decrementAndGet() > 0) run();  这种递归写法如果消费能力远远不如生产，就会出现栈内存溢出
        }
    }
}
